package com.dilidili.controller;

import com.dilidili.service.*;
import com.domain.History;
import com.domain.VT;
import com.domain.Video;
import com.dilidili.esentity.VideoPojo;
import com.dilidili.mapper.VideoPojoDao;
import com.dilidili.service.*;
import com.dilidili.service.impl.NiceVideoServiceImpl;
import com.domain.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.util.CommonResult;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.web.bind.annotation.RequestMethod;
import sun.rmi.runtime.Log;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import ws.schild.jave.MultimediaInfo;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.io.File;
import java.util.*;
import java.io.IOException;

/**
 * 【请填写功能名称】Controller
 *
 * @author ruoyi
 * @date 2022-03-31
 */
@RestController
@RequestMapping("/system/video")
public class VideoController {

    @Autowired
    private FileUpLoadService fileUploadService;
    @Resource
    private VideoPojoDao videoPojoDao;
   private RestHighLevelClient client = new RestHighLevelClient(
            //创建ES客户端
            RestClient.builder(
                    new HttpHost("localhost", 9200, "http")
            )
    );
    //注入 ElasticsearchRestTemplate
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Resource
    private IVideoService videoService;
    @Resource
    private VideoSharpnessService videoSharpnessService;
    @Resource
    private IUserService userService;
    @Autowired
    private IHistoryService historyService;

    @Autowired
    private IVTService vTService;
    @Autowired
    private INiceVideoService niceVideoService;
    /**
     *
     * @param videoTitle 标题
     * @param videoReprintsite 是否转载
     * @param url 视频地址
     * @param value 小分区
     * @param res 标签
     * @param request
     * @return
     */
    @Resource
    RedisTemplate redisTemplate;

    @RequestMapping("/add")
    public Object add(String videoTitle, Long videoReprintsite, @RequestParam(required = false, defaultValue = "") String url,
                      Long value, Long[] res,
                      HttpServletRequest request, String videoSuggest, Long Uid) throws IOException {
        List vs = (List) redisTemplate.opsForValue().get("file");

        Video video = new Video();
        video.setVideoTitle(videoTitle);
//        videoTitle,videoReprintsite,value,videoSuggest,Uid,new Date(),url,vs.get(2),vs.get(3)
        video.setVideoCreatetime(new Date());
        video.setVideoZoneId(value);
        video.setVideoVideotype(videoReprintsite);
        video.setVideoReprintsite(url);
        video.setVideoUserId(Uid);
        video.setVideoIsreprint(0L);
        video.setVideoState(1L);
        video.setVideoSuggest(videoSuggest);
        video.setVideoCover(vs.get(3) + "");
        video.setVideoLength(Long.parseLong(vs.get(4) + ""));
        videoService.insertVideo(video);
        for (Long re : res) {
            vTService.insertVT(new VT(re, video.getVideoId()));
        }
        String a = vs.get(0) + "";
        String a1 = vs.get(1) + "";
        String a2 = vs.get(2) + "";
        videoSharpnessService.add(a1, 0, video.getVideoId());
        videoSharpnessService.add(a2, 1, video.getVideoId());
        videoSharpnessService.add(a, 2, video.getVideoId());
        //
        esAdd(video);

        return CommonResult.success(200);
    }

    @RequestMapping("/add2")
    public Object add(String videoTitle, Long videoReprintsite, @RequestParam(required = false, defaultValue = "") String url,
                      Long value, Long[] res, String videoSuggest) throws IOException {
        List vs = (List) redisTemplate.opsForValue().get("file");
        Video video = new Video();
        video.setVideoTitle(videoTitle);
        video.setVideoCreatetime(new Date());
        video.setVideoZoneId(value);
        video.setVideoVideotype(videoReprintsite);
        video.setVideoReprintsite(url);
        video.setVideoIsreprint(0L);
        video.setVideoState(1L);
        video.setVideoSuggest(videoSuggest);
        video.setVideoCover(vs.get(3) + "");
        video.setVideoLength(Long.parseLong(vs.get(4) + ""));
        videoService.insertVideo(video);
        for (Long re : res) {
            vTService.insertVT(new VT(re, video.getVideoId()));
        }
        String a = vs.get(0) + "";
        String a1 = vs.get(1) + "";
        String a2 = vs.get(2) + "";
        videoSharpnessService.add(a1, 0, video.getVideoId());
        videoSharpnessService.add(a2, 1, video.getVideoId());
        videoSharpnessService.add(a, 2, video.getVideoId());
        esAdd(video);
        return "";
    }
    //elasticsearch添加方法 索引vedio
    private void esAdd(Video video) throws IOException {
        VideoPojo videoPojo = videoService.animatedRandomVideoId(video.getVideoId());
        if (videoPojo.getBarrages().size()>0){
            videoPojo.setBars(videoPojo.getBarrages().size());
        }else {
            videoPojo.setBars(1);
        }

        if (videoPojo.getCollectVideo().size()>0){
            videoPojo.setCvs(videoPojo.getCollectVideo().size());
        }else {
            videoPojo.setCvs(1);
        }
        //插入数据
        //同步es
        IndexRequest indexRequest = new IndexRequest();
        indexRequest.index("video").id(videoPojo.getVideoId()+"");
        //先es存储数据必须是json格式
        ObjectMapper m = new ObjectMapper();
        String jsonRest = m.writeValueAsString(videoPojo);
        indexRequest.source(jsonRest, XContentType.JSON );
        IndexResponse index = client.index(indexRequest, RequestOptions.DEFAULT);
    }

    @RequestMapping("/update")
    public String update(String videoTitle, String videoSuggest, Long vId) {
        List<Map> byVideoId = videoSharpnessService.getByVideoId(vId);
        List vs = (List) redisTemplate.opsForValue().get("file");
        if (byVideoId.size()<1){
            String a = vs.get(0) + "";
            String a1 = vs.get(1) + "";
            String a2 = vs.get(2) + "";
            videoSharpnessService.add(a, 0, vId);
            videoSharpnessService.add(a1, 1, vId);
            videoSharpnessService.add(a2, 2, vId);
        }

       Video video= new Video();
        video.setVideoSuggest(videoSuggest);
        video.setVideoTitle(videoTitle);
        video.setVideoId(vId);
        video.setVideoCover(vs.get(3) + "");
        video.setVideoLength(Long.parseLong(vs.get(4) + ""));
        video.setVideoState(1L);
        video.setVideoCreatetime(new Date());
        video.setVideoIsreprint(0L);
        videoService.updateVideo(video);
        return "0";
    }


    @Autowired
    private IHistoryService iHistoryService;
    @Autowired
    private IVTService ivtService;
    @Autowired
    private IReportService iReportService;
    //视频删除
    @Transactional(rollbackFor = Exception.class)
    @RequestMapping("/delVideo")
    public void deleteVideo(Long videoId){
        iBarrageService.delByVideoId(videoId);//弹幕
        iCollectVideoService.delByVideoId(videoId);//收藏
        iCommentService.delByVideoId(videoId);//评论
        iHistoryService.delByVideoId(videoId);//历史
        niceVideoService.delByVideoId(videoId);//点赞
        ivtService.delByVideoId(videoId);//标签视频关联表
        iReportService.delByVideoId(videoId);//举报
        videoSharpnessService.delByVideoId(videoId);//视频清晰度
        videoService.Tombstone(videoId);//视频
        videoPojoDao.deleteById(videoId);
    }

    @Autowired
    private ICommentService iCommentService;
    @Autowired
    private ICollectVideoService iCollectVideoService;
    @Autowired
    private IBarrageService iBarrageService;

    @RequestMapping("/query")
    public Object query(Long userId){
        HashMap<Object, Object> map = new HashMap<>();
        List<Video> list = videoService.queryByUserId(userId);
        Long dianji=0L;
        for (Video video : list) {
            dianji+=video.getVideoIsreprint();
        }
        List<Video> list2 = videoService.queryByUserIdContribute(userId);
        map.put("dianji",dianji);
        map.put("tougao",list2.size());
        map.put("dianzan",niceVideoService.queryByUserId(userId).size());
        map.put("pinglun",iCommentService.queryByUserId(userId).size());
        map.put("souchang",iCollectVideoService.queryByUserId(userId).size());
        map.put("danmu",iBarrageService.queryByUserId(userId).size());
        return map;
    }

    @RequestMapping("/byUserId")
    public List<Map> byUserId(Integer userId) {
      return   videoService.byUserId(userId);
    }
    //主页随机视频
    @RequestMapping("/animatedRandomVideo")
    public CommonResult animatedRandomVideo(Long smallzoneId) {
        return CommonResult.success(videoService.animatedRandomVideo(smallzoneId));
    }

    //主页排行榜随机视频
    @RequestMapping("/animatedRandomVideoLeaderboard")
    public CommonResult animatedRandomVideoLeaderboard(Long smallzoneId) {
        return CommonResult.success(videoService.animatedRandomVideoLeaderboard(smallzoneId));
    }

    //查询视频详情
    @RequestMapping("/animatedRandomVideoById")
    public CommonResult animatedRandomVideoById(Long videoId) {
        return CommonResult.success(videoService.animatedRandomVideoById(videoId));
    }

    //视频观看数和在线观看数+1 video_isreprint
    @RequestMapping("/animatedRandomVideoByIdUpd")
    public String editViewCount(Long videoId, String userId) {
        if (!StringUtils.isEmpty(userId)) {
            History history = new History(Long.parseLong(userId), videoId, new Date());
            List<History> histories = historyService.selectHistoryByHistory(history);
            if(histories.size()>0&&histories!=null){
                historyService.updateHistory(history);
            }else {
                historyService.insertHistory(history);
            }
        }
        Video video1 = videoService.animatedRandomVideoById(videoId);
        if (video1.getVideoIsreprint()==null||video1.getVideoIsreprint()==0L){
            video1.setVideoIsreprint(1L);
        }else {
            video1.setVideoIsreprint(video1.getVideoIsreprint()+1);
        }
        if(video1.getVideoOnline()==null||video1.getVideoIsreprint()==0L){
            video1.setVideoOnline(1L);
        }else{
            video1.setVideoOnline(video1.getVideoOnline()+1);
        }
        videoService.updateCount(video1);
        Video video = videoService.animatedRandomVideoById(videoId);
        if (video.getVideoIsreprint() == null) {
            video.setVideoIsreprint(1L);
        } else {
            video.setVideoIsreprint(video.getVideoIsreprint() + 1);
        }
        videoService.updateCount(video);
        return "1";
    }

    //修改视频删除
    @RequestMapping("/updateVideo")
    public String updateVideo(Long videoId){
        VideoPojo videoPojo = videoService.animatedRandomVideoId(videoId);
        String videoCover = videoPojo.getVideoCover();
        List<VideoSharpness> videoSharpnesses = videoPojo.getVideoSharpnesses();
        videoSharpnessService.delByVideoId(videoPojo.getVideoId());
        videoService.updateImg(Integer.parseInt(videoId+""));
        return "0";
    }
//    //查看弹幕总数
//    @RequestMapping("/findCountBarrage")
//    public
    //主页轮播图随机
    @RequestMapping("/animatedRandomVideoFour")
    public CommonResult animatedRandomVideoFour() {
        return CommonResult.success(videoService.animatedRandomVideoFour());
    }

    //主页轮播图右侧随机
    @RequestMapping("/animatedRandomVideoSix")
    public CommonResult animatedRandomVideoSix() {
        return CommonResult.success(videoService.animatedRandomVideoSix());
    }

    @RequestMapping("/Submission")
    public Object Submission(Integer userId, Integer bigzoneId, Integer videoState,
                             @RequestParam(defaultValue = "1", required = false) Integer pageNum,
                             @RequestParam(defaultValue = "5", required = false) Integer pageSize)
    {
        PageHelper.startPage(pageNum, pageSize);
        List<Map> submission = videoService.Submission(userId, bigzoneId, videoState);
        PageInfo pageInfo = new PageInfo(submission);
        return pageInfo;
    }
    //关闭页面视频在线人数-1
    @RequestMapping("delVideoOnline")
    public Object delVideoOnline(Integer videoid){
        return videoService.delVideoOnline(videoid);
    }
    //获取视频的弹幕总数
    @RequestMapping("getVideoBarrageCount")
    public Object getVideoBarrageCount(Integer videoid){
        return videoService.getVideoBarrageCount(videoid);
    }
    //获取该视频的所有弹幕列表
    @RequestMapping("getVideoBarrageList")
    public Object getVideoBarrageList(Integer videoid){
        return videoService.getVideoBarrageList(videoid);
    }
    //获取该用户是否关注视频作者，是否点赞视频，是否收藏
    @RequestMapping("findVideoNiceCollectFans")
    public Object findVideoNiceCollectFans(Integer videoId,Integer userId,Integer bigvId){
        Map map=new HashMap();
        List<Map> result1=videoService.getNice(userId,videoId);
        List<Map> result2=videoService.getCollect(userId,videoId);
        List<Map> result3=videoService.getFans(userId,bigvId);
        Map result4=videoService.getNiceNum(videoId);
        Map result5=videoService.getCollectNum(videoId);
        Map result6=userService.getBigvMes(bigvId);
        map.put("nice",result1);
        map.put("collect",result2);
        map.put("fans",result3);
        map.put("niceNum",result4);
        map.put("collectNum",result5);
        map.put("bigvMes",result6);
        return map;
    }

    @RequestMapping("fansQuery")
    public List<Map> getFans(Integer userId, Integer bigvId){
        return videoService.getFans(userId,bigvId);
    }

        @RequestMapping("/animatedRandomVideoAll")
    public Object animatedRandomVideoAll() throws Exception {
        List<VideoPojo> list = videoService.animatedRandomVideoAll();
//        videoPojoDao.saveAll(list);
        //
        for (VideoPojo videoPojo : list) {
            if (videoPojo.getBarrages().size()>0){
                videoPojo.setBars(videoPojo.getBarrages().size());
            }else {
                videoPojo.setBars(1);
            }

            if (videoPojo.getCollectVideo().size()>0){
                videoPojo.setCvs(videoPojo.getCollectVideo().size());
            }else {
                videoPojo.setCvs(1);
            }


            //插入数据
            IndexRequest indexRequest = new IndexRequest();
            indexRequest.index("video").id(videoPojo.getVideoId()+"");
            //先es存储数据必须是json格式
            ObjectMapper m = new ObjectMapper();
            String jsonRest = m.writeValueAsString(videoPojo);
            indexRequest.source(jsonRest, XContentType.JSON );
            IndexResponse index = client.index(indexRequest, RequestOptions.DEFAULT);
            System.out.println(index);
        }
        return "1";
    }
    @RequestMapping("/aa")
    public Object a() {
        List<VideoPojo> list = videoService.animatedRandomVideoAll();
        return list;
    }


    /**
     *
     * @param search 模糊查询
     * @param sort 排序，比如 按点赞数排序，点击量排序
     *             0：综合排序
     *             1：最多点击
     *             2：最新发布
     *             3：最多弹幕
     *             4：最多收藏
     * @param dateLength 时间，比如，十分钟，三十分组
     *                   0：全部时长
     *                   1：10分钟以下
     *                   2：10-30分钟
     *                   3：30-60分钟
     *                   4：60分钟以上
     * @param partition 小分区
     * @param bigzoneId 大分区
     * @return
     */
    @RequestMapping("/queryCondition")
    public Object queryCondition(String search,Integer sort,Integer dateLength,Integer partition,Integer bigzoneId,
                                 @RequestParam(defaultValue = "1", required = false) Integer currentPage,
                                 @RequestParam(defaultValue = "5", required = false) Integer pageSize) throws IOException
    {

        if (org.springframework.util.StringUtils.isEmpty(search)) {
            return null;
        }
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("video");
        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
        //        模糊查询
//        WildcardQueryBuilder query = QueryBuilders.wildcardQuery("videoTitle.keyword", "*"+search+"*");
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        boolQueryBuilder.must(QueryBuilders.wildcardQuery("videoTitle.keyword", "*"+search+"*"));
        boolQueryBuilder.must( QueryBuilders.matchPhraseQuery("videoTitle", "*"+search+"*"));//中文
        if (bigzoneId!=0&&bigzoneId!=null){
            boolQueryBuilder.must(QueryBuilders.matchQuery("bid", bigzoneId));
            if(partition!=0&&partition!=null){
                //小分区
                boolQueryBuilder.must(QueryBuilders.matchQuery("videoZoneId", partition));
            }
        }
        //根据视频时长查询 video_length
        if (dateLength==1){
            boolQueryBuilder.must( QueryBuilders.rangeQuery("videoLength").gte(0).lt(600));
        }else if(dateLength==2){
            boolQueryBuilder.must( QueryBuilders.rangeQuery("videoLength").gte(600).lt(1800));
        }else if(dateLength==3){
            boolQueryBuilder.must( QueryBuilders.rangeQuery("videoLength").gte(1800).lt(3600));
        }else if(dateLength==4){
            boolQueryBuilder.must( QueryBuilders.rangeQuery("videoLength").gte(3600));
        }
//        builder.query(query);



        //分页
        builder.query(boolQueryBuilder);

        //sort排序方式
        if(sort==1){
            builder.sort("videoIsreprint", SortOrder.DESC);
        }else if(sort==2){
            builder.sort("videoCreatetime", SortOrder.DESC);
        }else if(sort==3){
            builder.sort("bars", SortOrder.DESC);
        }else if(sort==4){
            builder.sort("cvs", SortOrder.DESC);
        }
        builder.from(currentPage);
        builder.size(pageSize);
        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        highlightBuilder.field("videoTitle");
        builder.highlighter(highlightBuilder);
        searchRequest.source(builder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        for (SearchHit hit : response.getHits().getHits()) {
            //解析高亮的字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField title = highlightFields.get("videoTitle");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果！
            if (title!=null){
                Text[] fragments = title.fragments();
                String n_title="";
                for (Text text : fragments) {
                    n_title+=text;
                }
                sourceAsMap.put("videoTitle",n_title);
            }
//            list.add(hit.getSourceAsMap());
        }
        return hits;
    }
    @RequestMapping("/del")
    public Object del(){
        videoPojoDao.deleteAll();
        return "";
    }
    @RequestMapping("/find")
    public Object find() throws IOException {

        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("video");
        searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        System.out.println(hits.getTotalHits());
        System.out.println(response.getTook());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
        return hits;
    }

    @RequestMapping("/randomVideo")
    public List<Video> randomVideo() {
        return videoService.randomVideo();
    }


    /**
     * 用户所有视频总点赞数请求
     * @param userId
     * @return
     */
    @RequestMapping(value = "/easyNum",method = RequestMethod.GET)
    public Long easyNum(Long userId) {
        return videoService.easyNum(userId);
    }
}
